﻿#include "CNewConnection.h"
#include <poco/Util/Application.h>
#include <poco/Timespan.h>
#include <poco/LocalDateTime.h>
#include <poco/DateTimeFormatter.h>
#include <spdlog/spdlog.h>
#include <Poco/ThreadPool.h>
#include <Poco/Thread.h>
#include <fmt/format.h>
#include "TaskDistributeThread.h"
#include "TaskHandlerThread.h"
#include "MyDalyLog.h"

CNewConnection::CNewConnection(const Poco::Net::StreamSocket& socket)
	:TCPServerConnection(socket)
{
	taskCenter = std::shared_ptr<CTaskCenter>(new CTaskCenter());
	isQuit = std::make_shared<std::atomic_bool>(false);
}

CNewConnection::~CNewConnection() {
}

//处理函数，是一个单独线程
void CNewConnection::run() {
	Poco::Util::Application& app = Poco::Util::Application::instance();

	//客户端信息,IP:port
	std::string clientFlag_ = this->socket().peerAddress().toString();
	Info(fmt::format("新客户端[{}]连接成功，处理线程[{}:{}]", clientFlag_, Poco::Thread::current()->getName(), (int)Poco::Thread::current()->currentOsTid()));

	std::string msg;
	
	//启动任务分配线程
	std::shared_ptr<Poco::Thread> threadTaskDistribute = std::shared_ptr<Poco::Thread>(new Poco::Thread());
	TaskDistributeThread runnableThreadDistribute(taskCenter,this->socket(), isQuit);
	threadTaskDistribute->start(runnableThreadDistribute);
	
	try{
		//链接最近活跃时间，用于计算链接沉默时长，关闭长时间沉默的链接
		Poco::LocalDateTime last_active_time = Poco::LocalDateTime();
		//收包缓存
		Poco::Buffer<char> recv_buf(MAX_SEND_RECV_BUF);
		while (true) {
			recv_buf.clear();

			int recv_len = socket().receiveBytes(recv_buf, 0, Poco::Timespan(0, 100));
			if (recv_len <= 0) {
				/************无数据处理**************/
				int err_code = socket().lastError();
				if (err_code == 0) {//0：操作完成
					Info(fmt::format("客户端[{}]断开，即将退出", clientFlag_));
					break;
				}
				else if (err_code == 258) {//258：接收超时，只有配置文件中设置的超时时间大于0时，才会计算超时
					int timeoutLimit = app.config().getInt("App.WaitTimeout");
					Poco::Timespan ts = Poco::LocalDateTime() - last_active_time;
					if ((timeoutLimit > 0) && (ts.seconds() >= timeoutLimit)){
						Info(fmt::format("客户端[{}]，长时间无响应，即将退出", clientFlag_));
						break;
					}
				}
				else {//其他错误码
					Info(fmt::format("客户端[{}]，接收错误，错误码:{}", clientFlag_, err_code));
					break;
				}
			}
			else {
				/*********有数据，开始处理*******/

				//更新时间戳
				last_active_time = Poco::LocalDateTime();

				if (app.config().getBool("Log.PringDebug")) {
					Info(fmt::format("连接[{}]，接收数据：{}", clientFlag_, std::string(recv_buf.begin(), recv_buf.size())));
				}

				//接收数据进入任务中心
				CTaskData task;
				task.recvData_ = recv_buf;
				taskCenter->Push(task);
			}
		}

		Info(fmt::format("客户端[{}]，接收线程关闭", clientFlag_));
	}
	catch (Poco::Exception& e) {
		Info(fmt::format("客户端[{}]，连接异常，code=[{}]，详情：{}，强制关闭",clientFlag_, e.code(), e.displayText()));
		goto EXIT_THREAD;
	}

EXIT_THREAD:
	isQuit->exchange(true);

	//等待任务分配线程
	threadTaskDistribute->join();
	socket().close();
}